package com.stormragetech.teamwork.spring.dao.impl;

import com.stormragetech.common.exception.StormragetechException;
import com.stormragetech.teamwork.common.constant.Constants;
import com.stormragetech.teamwork.entity.TwUser;
import com.stormragetech.teamwork.model.TwUserPermView;
import com.stormragetech.teamwork.spring.dao.TwUserMongo;
import lombok.extern.log4j.Log4j2;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;

import java.util.List;

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;

/**
 * description: //TODO
 *
 * @author: Xue Bin
 * @version: 1.0.0-SNAPSHOT
 */
@Log4j2
@Repository
public class TwUserMongoImpl implements TwUserMongo {

    private final MongoTemplate template;

    public TwUserMongoImpl(MongoTemplate template) {
        Assert.notNull(template, "MongoTemplate cannot be null !!!");
        this.template = template;
    }


    @Override
    public void create(final TwUser entity) throws StormragetechException {

        try {

            template.insert(entity, Constants.TW_USER_COL);
        } catch (Exception e) {
            throw new StormragetechException(Constants.MONGO_ERR_CODE, e.getMessage(), e);
        }
    }

    @Override
    public TwUser findByUsername(final String name) throws StormragetechException {

        try {

            Query query = new Query(Criteria.where("uname").is(name));
            return template.findOne(query, TwUser.class, Constants.TW_USER_COL);
        } catch (Exception e) {
            throw new StormragetechException(Constants.MONGO_ERR_CODE, e.getMessage(), e);
        }
    }

    public List<TwUserPermView> aggregation(final String name) {

        Aggregation aggregation = Aggregation.newAggregation(
                project("user_id", "uname"),
                lookup("tw_user_pos", "user_id", "user_id", "tw_user_pos"),
                unwind("tw_user_pos"),
                match(Criteria.where("tw_user.uname").is(name))
        );

        AggregationResults<TwUserPermView> results = template.aggregate(aggregation, "tw_user", TwUserPermView.class);
        return results.getMappedResults();

    }
}
